package com.xinqi.modules.homework.homework.assistant.service.impl;

import com.alibaba.fastjson2.JSON;
import com.xinqi.common.base.enums.YesNoEnum;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.response.R;
import com.xinqi.common.core.constant.Constants;
import com.xinqi.common.core.enums.*;
import com.xinqi.modules.chat.chat.official.dto.req.ChatAssistantContentCreateDTO;
import com.xinqi.modules.chat.chat.official.json.BaseMessage;
import com.xinqi.modules.chat.chat.official.json.HomeWorkMessage;
import com.xinqi.modules.chat.chat.rongyun.RemoteRongyunClient;
import com.xinqi.modules.chat.chat.template.TemplateMessageDTO;
import com.xinqi.modules.course.classromm.dto.NoticeDTO;
import com.xinqi.modules.course.clazz.client.ClassClient;
import com.xinqi.modules.course.clazz.client.ClassGroupClient;
import com.xinqi.modules.course.clazz.client.ClassGroupStudentClient;
import com.xinqi.modules.course.clazz.client.ClassStudentClient;
import com.xinqi.modules.course.clazz.dto.rsp.ClassGroupResultDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassGroupStudentResultDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassResultDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import com.xinqi.modules.homework.homework.assistant.convert.AssistantConvert;
import com.xinqi.modules.homework.homework.assistant.service.AssistantHomeworkService;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkEntity;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkStudentLogEntity;
import com.xinqi.modules.homework.homework.service.CourseHomeworkService;
import com.xinqi.modules.homework.homework.utils.MathUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Log4j2
@Service("assistantHomeworkService")
@RequiredArgsConstructor
public class AssistantHomeworkServiceImpl implements AssistantHomeworkService {

    private final AssistantConvert assistantConvert;

    private final ClassClient classClient;

    private final ClassStudentClient classStudentClient;

    private final ClassGroupClient classGroupClient;

    private final ClassGroupStudentClient classGroupStudentClient;

    @Lazy
    private final CourseHomeworkService courseHomeworkService;

    private final RemoteRongyunClient remoteRongyunClient;

    /**
     * 新奇助手作业发布
     *
     * @author dzy
     */
    @Override
    public List<ChatAssistantContentCreateDTO> releaseHomework(Long contentId) {
        // 作业发布默认第一轮
        CourseHomeworkEntity entity = courseHomeworkService.getById(contentId);
        if (Objects.isNull(entity)) {
            return null;
        }
        // 获取消息名称
        String typeName = this.getHomeworkTypeName(entity);

        // 获取班级成员信息
        List<ClassStudentResultDTO> students = this.getClassStudentList(entity);


        List<ChatAssistantContentCreateDTO> list = new ArrayList<>();

        ChatAssistantContentCreateDTO initCreate = this.initChatAssistantContent(AssistantMessageTypeEnum.HOMEWORK);
        HomeWorkMessage initMessage = this.initHomeworkMessage(entity);

        students.forEach(item -> {
            ChatAssistantContentCreateDTO create = assistantConvert.create(initCreate);
            create.setContentId(contentId);
            create.setTimes(entity.getCurrRepeatDay());
            create.setRecipient(item.getStudentId());
            // 作业消息体
            HomeWorkMessage homeWorkMessage = assistantConvert.create(initMessage);
            homeWorkMessage.setClassRole(item.getClassRole());
            // 老师助教发送统计数据
            if (Objects.equals(ClassRoleEnum.TEACHER, item.getClassRole())
                || Objects.equals(ClassRoleEnum.ASSISTANT, item.getClassRole())) {
                homeWorkMessage.setParticipateNum(0);
                homeWorkMessage.setNotParticipateNum(0);
                homeWorkMessage.setHomeworkType(typeName);
                create.setSubmittedState(AssistantStateEnum.VIEW_DETAIL.getCode());
            } else {
                create.setSubmittedState(AssistantStateEnum.NOT_SUBMITTED.getCode());
                // 判断作业轮数 显示不同标题
                if (Objects.equals(YesNoNumberEnum.YES.getCode(), entity.getIsRepeat())) {
                    homeWorkMessage.setTitle(homeWorkMessage.getTitle() + "(第" + entity.getCurrRepeatDay() + "轮)");
                }
                // 判断作业类型 显示不同作业名称
                if (Objects.equals(HomeWorkTypeEnum.TASK_PERSONAL.getCode(), entity.getTaskType())) {
                    homeWorkMessage.setHomeworkType(HomeWorkTypeEnum.TASK_PERSONAL.getDescription());
                } else {
                    homeWorkMessage.setHomeworkType(HomeWorkTypeEnum.TASK_GROUP.getDescription());
                }
            }
            create.setMessageContext(JSON.toJSONString(homeWorkMessage));
            list.add(create);
        });
        return list;
    }

    /**
     * 根据作业类型获取要发送学生列表
     */
    private List<ClassStudentResultDTO> getClassStudentList(CourseHomeworkEntity entity) {
        // 获取班级所有成员信息
        List<ClassStudentResultDTO> students = R.as(classStudentClient.allUserListByClassId(entity.getClassId()));
        // 获取老师以及关系用户信息
        students = students.stream().filter(student -> Objects.equals(YesNoNumberEnum.YES.getCode(), student.getIsRelationalStudent())
            || Objects.equals(YesNoNumberEnum.YES.getCode(), student.getIsTeacher())).collect(Collectors.toList());
        if (Objects.equals(HomeWorkTypeEnum.TASK_PERSONAL.getCode(), entity.getTaskType())) {
            return students;
        } else {
            List<Long> groupIds = Arrays.stream(entity.getGroupIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
            //查询学生ID
            List<ClassGroupStudentResultDTO> groupStudentList = R.as(classGroupStudentClient.findStudentListByGroupIds(groupIds));
            List<Long> studentIds = groupStudentList.stream().map(groupStudent -> groupStudent.getStudentId()).collect(Collectors.toList());
            List<ClassStudentResultDTO> allList = new ArrayList<>();
            students.forEach(item -> {
                if (Objects.equals(ClassRoleEnum.TEACHER, item.getClassRole())
                    || Objects.equals(ClassRoleEnum.ASSISTANT, item.getClassRole())) {
                    allList.add(item);
                } else {
                    // 主学生不为空以及成员列表关系是主学生信息
                    if (CollectionUtils.isNotEmpty(studentIds) && studentIds.contains(item.getPatStuRefId())) {
                        allList.add(item);
                    }
                }
            });
            return allList;
        }
    }


    /**
     * 新奇助手作业催交、打回、成绩
     *
     * @param contentId 作业成绩
     * @param times     作业轮数
     * @param opType    操作类型 1：催交 2打回 3成绩
     */
    @Override
    public List<ChatAssistantContentCreateDTO> operaStudentHomework(Long contentId, Integer times, List<CourseHomeworkStudentLogEntity> students, Integer opType, String repulseReason) {
        CourseHomeworkEntity entity = courseHomeworkService.getById(contentId);
        if (CollectionUtils.isEmpty(students)) {
            return null;
        }
        List<Long> studentIds = students.stream().map(studentLog -> studentLog.getStudentId()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(students)) {
            return null;
        }

        Map<Long, Long> recordMap = new HashMap<>();
        if (Objects.equals(AssistantTypeEnum.REPULSE.getCode(), opType)) {
            recordMap = students.stream().collect(Collectors.toMap(v -> v.getStudentId(), v -> v.getRecordId()));
        }

        // 查询学生关系用户信息
        List<ClassStudentResultDTO> relationshipList = R.as(classStudentClient.findClassRelationshipStudentList(entity.getClassId(), studentIds));

        // 遍历发送消息实体
        List<ChatAssistantContentCreateDTO> list = new ArrayList<>();
        HomeWorkMessage initMessage = this.initHomeworkMessage(entity);
        for (ClassStudentResultDTO item : relationshipList) {
            ChatAssistantContentCreateDTO create = this.initChatAssistantContent(AssistantMessageTypeEnum.HOMEWORK);
            create.setType(opType);
            create.setContentId(entity.getId());
            create.setTimes(entity.getRepeatDay());
            create.setRecipient(item.getStudentId());
            create.setProgressState(checkProgressState(entity).getCode());
            // 作业消息体
            HomeWorkMessage homeWorkMessage = assistantConvert.create(initMessage);
            homeWorkMessage.setClassRole(item.getClassRole());
            if (Objects.equals(AssistantTypeEnum.CALL.getCode(), opType)) {
                create.setSubmittedState(AssistantStateEnum.NOT_SUBMITTED.getCode());
            }
            if (Objects.equals(AssistantTypeEnum.REPULSE.getCode(), opType)) {
                create.setSubmittedState(AssistantStateEnum.NOT_SUBMITTED.getCode());
                homeWorkMessage.setReason(repulseReason);
            }
            if (Objects.equals(AssistantTypeEnum.SCORE.getCode(), opType)) {
                create.setSubmittedState(AssistantStateEnum.SUBMITTED.getCode());
                CourseHomeworkStudentLogEntity studentLog = students.stream().filter(a ->
                    Objects.equals(item.getPatStuRefId(), a.getStudentId())).findFirst().orElse(null);
                CourseHomeworkStudentLogEntity oldStudentLog = students.stream().filter(a ->
                    Objects.equals(item.getStudentId(), a.getStudentId())).findFirst().orElse(null);
                if (Objects.nonNull(studentLog)) {
                    homeWorkMessage.setScore(MathUtils.stripTrailingZeros(studentLog.getStudentScore(), 1));
                } else if (Objects.nonNull(oldStudentLog)) {
                    homeWorkMessage.setScore(MathUtils.stripTrailingZeros(oldStudentLog.getStudentScore(), 1));
                }
                homeWorkMessage.setSubmission(AssistantStateEnum.VIEW_DETAIL.getCode());
            }
            // 判断作业轮数 显示不同标题
            if (entity.getRepeatDay() > 1) {
                homeWorkMessage.setTitle(homeWorkMessage.getTitle() + "(第" + times + "轮)");
            }
            // 判断作业类型 显示不同作业名称
            if (Objects.equals(HomeWorkTypeEnum.TASK_PERSONAL.getCode(), entity.getTaskType())) {
                homeWorkMessage.setHomeworkType(HomeWorkTypeEnum.TASK_PERSONAL.getDescription());
            } else {
                homeWorkMessage.setHomeworkType(HomeWorkTypeEnum.TASK_GROUP.getDescription());
            }
            homeWorkMessage.setRecordId(recordMap.get(item.getPatStuRefId()));
            create.setMessageContext(JSON.toJSONString(homeWorkMessage));
            list.add(create);
        }
        return list;
    }

    /**
     * 初始化发布基本消息体
     */
    private ChatAssistantContentCreateDTO initChatAssistantContent(AssistantMessageTypeEnum type) {
        // 初始化基本信息
        ChatAssistantContentCreateDTO assistant = new ChatAssistantContentCreateDTO();
        assistant.setType(AssistantTypeEnum.RELEASE.getCode());
        assistant.setMessageType(type.getType());
        assistant.setProgressState(AssistantStateEnum.PROGRESS.getCode());
        return assistant;
    }

    /**
     * 初始化消息内容公共方法
     */
    private HomeWorkMessage initHomeworkMessage(CourseHomeworkEntity entity) {
        BaseMessage base = this.initBaseMessage(entity.getClassId());
        HomeWorkMessage message = JSON.parseObject(JSON.toJSONString(base), HomeWorkMessage.class);
        message.setTitle(entity.getTitle());
        message.setClassId(entity.getClassId());
        message.setContentId(entity.getId());
        message.setTaskType(entity.getTaskType());
        message.setEndTime(entity.getEndTime());
        // 判断作业轮数 赋值 新奇助手作业 轮数信息
        if (Objects.equals(Integer.parseInt(YesNoEnum.YES.getCode()), entity.getIsRepeat())
            && Objects.nonNull(entity.getRepeatedDay())) {
            message.setHomeworkRound(entity.getRepeatedDay() + "/" + entity.getRepeatDay());
            message.setCurrent(entity.getRepeatedDay().toString());
            message.setTotal(entity.getRepeatDay().toString());
        }
        if (Objects.equals(Integer.parseInt(YesNoEnum.NO.getCode()), entity.getLimitStatus())) {
            message.setSubmission(AssistantStateEnum.PROHIBIT_SUBMISSION.getCode());
        } else {
            message.setSubmission(AssistantStateEnum.ALLOW_SUBMISSION.getCode());
        }
        return message;
    }

    /**
     * 初始化发布基本消息内容
     */
    private BaseMessage initBaseMessage(Long classId) {
        // 获取班级信息
        ClassResultDTO classResult = R.as(classClient.findClass(classId));
        BaseMessage message = new BaseMessage();
        if (Objects.nonNull(classResult)) {
            message.setCourseName(classResult.getCourseName() + Constants.SPACE_DROP + classResult.getName());
            message.setClassId(classId);
        } else {
            message.setCourseName("" + Constants.SPACE_DROP + "");
            message.setClassId(classId);
        }
        return message;
    }

    /**
     * 根据作业类型获取作业类型名称
     */
    private String getHomeworkTypeName(CourseHomeworkEntity entity) {
        if (Objects.equals(HomeWorkTypeEnum.TASK_PERSONAL.getCode(), entity.getTaskType())) {
            return HomeWorkTypeEnum.TASK_PERSONAL.getDescription();
        } else {
            //查找小组groupQuery
            List<Long> groupIds = Arrays.stream(entity.getGroupIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
            List<ClassGroupResultDTO> groupList = R.as(classGroupClient.selectList(groupIds));
            StringBuilder stringBuilder = new StringBuilder(HomeWorkTypeEnum.TASK_GROUP.getDescription());
            stringBuilder.append("(");
            //拼接小组名称
            for (int i = 0; i < groupList.size(); i++) {
                ClassGroupResultDTO groupResult = groupList.get(i);
                if (i < groupList.size() - 1) {
                    stringBuilder.append(groupResult.getName());
                    stringBuilder.append(",");
                } else {
                    stringBuilder.append(groupResult.getName());
                }
            }
            return stringBuilder.append(")").toString();
        }
    }

    /**
     * 校验作业状态
     */
    private AssistantStateEnum checkProgressState(CourseHomeworkEntity entity) {
        if (Objects.equals(HomeWorkStatusEnum.IN_PROGRESS.getCode(), entity.getStatus())) {
            return AssistantStateEnum.PROGRESS;
        } else if (Objects.equals(HomeWorkStatusEnum.CLOSED.getCode(), entity.getStatus())) {
            return AssistantStateEnum.ENDED;
        } else {
            return AssistantStateEnum.NOT_STARTED;
        }
    }

    /**
     * 提交作业发送系统通知
     * @author dzy
     */
    @Override
    public void submitSysChat(Long classId, Long contentId, Long studentId, Integer times) {
        ClassStudentResultDTO mainStudent = R.as(classStudentClient.findVirtualClassStudentByClassIdAndUserId(classId, studentId));
        List<ClassStudentResultDTO> userList = R.as(classStudentClient.findContainsTeacherListByClassId(classId));
        // 老师助教 ID集合
        List<String> teacherIdList = userList.stream().filter(v -> Objects.equals(YesNoNumberEnum.YES.getCode(), v.getIsTeacher()))
            .map(v -> v.getStudentId() + "").collect(Collectors.toList());
        if (CollectionUtils.isEmpty(teacherIdList)) {
            return;
        }
        String[] teacherIds = teacherIdList.toArray(new String[teacherIdList.size()]);

        if (Objects.isNull(mainStudent) || teacherIds.length == 0) {
            return;
        }

        TemplateMessageDTO message = new TemplateMessageDTO();
        message.setType(SysMessageEnum.COURSE_TASK_SUBMIT.getCode());
        message.setClassId(classId.toString());
        Map<String, Object> content = new HashMap<>();
        content.put("type", SysMessageEnum.COURSE_TASK_SUBMIT.getCode());
        content.put("classId", classId.toString());
        content.put("contentId", contentId.toString());
        content.put("tiems", times);
        content.put("studentId", mainStudent.getStudentId().toString());
        content.put("avatar", mainStudent.getAvatar());
        content.put("studentName", mainStudent.getStudentName());
        content.put("xinqiNumber", mainStudent.getXinqiNumber());
        content.put("content", "【" + mainStudent.getStudentName() + "】" + "有新的作业提交");
        message.setContent(JSON.toJSONString(content));
        message.setFromUserId("0");
        message.setToUserId(classId.toString());
        remoteRongyunClient.creatSysUserSend(teacherIds, JSON.toJSONString(message));
    }

}
